package edu.pw.p2pclient.logic;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

import android.os.Handler;
import android.os.Looper;
import edu.pw.p2pclient.data.AvailableAdapter;
import edu.pw.p2pclient.data.RemoteDeviceInfo;
import edu.pw.p2pclient.data.Resource;
import edu.pw.p2pclient.networking.CommunicationService;

public class AvailableManager implements Serializable {

	private static final long serialVersionUID = 6187809545349787342L;

	private static AvailableManager mInstance = null;
	private AvailableAdapter mAdapter = null;
	private HashMap<String, HashSet<RemoteDeviceInfo>> mDevicesWithResource = null;

	private AvailableManager() {
		mAdapter = new AvailableAdapter();
		mDevicesWithResource = new HashMap<String, HashSet<RemoteDeviceInfo>>();
	}

	public static AvailableManager getInstance() {

		if (mInstance == null)
			mInstance = new AvailableManager();
		return mInstance;
	}

	public AvailableAdapter getAdapter() {
		return mAdapter;
	}

	public LinkedHashSet<Resource> getResources() {
		return mAdapter.getResources();
	}

	public HashMap<String, HashSet<RemoteDeviceInfo>> getDevicesWithResource() {
		return mDevicesWithResource;
	}

	public void updateResources(RemoteDeviceInfo device) {
		for (Resource res : device.getResources()) {
			Set<RemoteDeviceInfo> infos = mDevicesWithResource
					.get(res.getCrc());
			if (infos == null) {
				HashSet<RemoteDeviceInfo> set = new HashSet<RemoteDeviceInfo>();
				set.add(device);
				mDevicesWithResource.put(res.getCrc(), set);
			} else
				infos.add(device);
		}
		updateResourcesView();
	}

	public void updateResourcesView() {
		mAdapter.clear();
		CommunicationService commService = CommunicationService.getInstance();
		if (commService == null)
			return;

		ArrayList<RemoteDeviceInfo> devices = commService.getKnownDevices();
		for (RemoteDeviceInfo device : devices) {
			if (device.getResources() == null
					|| device.getResources().size() == 0)
				continue;
			mAdapter.addAllAvailable(device.getResources());
		}
		Handler handler = new Handler(Looper.getMainLooper());
		handler.post(new Runnable() {

			@Override
			public void run() {

				mAdapter.notifyDataSetChanged();
			}
		});
	}

	public void disconnected() {
		mAdapter.clear();
		mDevicesWithResource.clear();
		mAdapter.notifyDataSetChanged();
	}

	public void deviceRemoved(RemoteDeviceInfo device) {
		if (device == null || device.getResources() == null)
			return;
		for (Resource resource : device.getResources()) {
			if (mDevicesWithResource.get(resource.getCrc()) != null) {
				mDevicesWithResource.get(resource.getCrc()).remove(device);
				if (mDevicesWithResource.get(resource.getCrc()).size() == 0)
					mDevicesWithResource.remove(resource.getCrc());
			}
			mAdapter.remove(resource);
		}
		CommunicationService.getInstance().removeKnownDevice(device);
		AvailableManager.getInstance().updateResourcesView();
	}

}
